package com.traffic.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.traffic.annotation.Power;
import com.traffic.constant.Const;
import com.traffic.constant.Status;
import com.traffic.entity.Admin;
import com.traffic.entity.QueryResult;
import com.traffic.entity.Role;
import com.traffic.exception.BaseException;
import com.traffic.mapper.AdminMapper;
import com.traffic.mapper.RoleMapper;
import com.traffic.service.AdminService;
import com.traffic.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by IntelliJ IDEA.
 * User: KingRainGrey
 * Date: 2020/9/8
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 管理员注册账户
     * @param account
     * @param password
     * @return
     */
    @Override
    public Admin register(String account, String password) {
        String salt = Const.SALT_PREFIX + IdUtil.fastSimpleUUID();
        Admin admin = Admin.builder().account(account).salt(salt).password(SecureUtil.md5(salt + password)).status(Const.ACCOUNT_NORMAL_TAG).build();
        adminMapper.insert(admin);
        return admin;
    }

    /**
     * 管理员登录
     * @param account
     * @param password
     * @return
     */
    @Override
    public String login(String account, String password) {
        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.eq("account", account);
        Admin admin = adminMapper.selectOne(wrapper);
        if (ObjectUtil.isNotNull(admin)) {
            if (StrUtil.equals(admin.getPassword(), SecureUtil.md5(admin.getSalt() + password))) {
                // 登录成功 更新登录时间
                admin.setLastLoginTime(new DateTime());
                adminMapper.updateById(admin);

                // 检查token
                String key = Const.TOKEN_PREFIX + admin.getAccount();
                String oldToken = stringRedisTemplate.opsForValue().get(key);
                if (StrUtil.isNotEmpty(oldToken)) {
                    stringRedisTemplate.delete(key);
                }
                String token = JwtUtil.sign(admin);
                stringRedisTemplate.opsForValue().set(key, token);
                return token;
            }
        }
        return null;
    }

    /**
     * 管理员注销登录 清空token
     * @return
     */
    @Override
    public boolean logout() {
        String account = jwtUtil.getAccount(Const.TAG_ADMIN);
        if (jwtUtil.confirm(account)) {
            stringRedisTemplate.delete(Const.TOKEN_PREFIX + account);
            return true;
        }
        return false;
    }

    /**
     * 查询单个管理员
     * @param account
     * @return
     */
    @Override
    public Admin get(String account) {
        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.eq("account", account);
        Admin admin = adminMapper.selectOne(wrapper);
        if (ObjectUtil.isNotNull(admin)) {
            Role role = roleMapper.selectById(admin.getRole());
            if (ObjectUtil.isNotNull(role)) {
                admin.setRoleName(role.getName());
            }
        }
        return admin;
    }

    /**
     * 高级管理员修改普通管理员信息
     * @param admin
     * @return
     */
    @Override
    @Power(authority = Const.AUTH_ADMIN)
    public Admin editAdminInfo(Admin admin) {
        adminMapper.updateById(admin);
        return admin;
    }

    /**
     * 最高权限管理员 删除低权限管理员
     * @param adminId
     * @return
     */
    @Override
    @Power(authority = Const.AUTH_DELETE)
    public Boolean delete(Long adminId) {
        if (adminMapper.deleteById(adminId) > 0) {
            return true;
        }
        return false;
    }

    /**
     * 查询管理员列表
     * 分页
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    @Power(authority = Const.AUTH_ADMIN)
    public QueryResult queryAdmins(Integer currentPage, Integer pageSize) {
        IPage<Admin> adminPage = new Page<>(currentPage, pageSize);
        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        // add where
        wrapper.orderByAsc("id");
        IPage<Admin> page = adminMapper.selectPage(adminPage, wrapper);
        Integer total = adminMapper.selectCount(wrapper);
        List<Admin> list = page.getRecords();
        list.forEach(admin -> {
            if (ObjectUtil.isNotNull(admin)) {
                Role role = roleMapper.selectById(admin.getRole());
                if (ObjectUtil.isNotNull(role)) {
                    admin.setRoleName(role.getName());
                }
            }
        });
        QueryResult result = QueryResult.builder().data(list).total(total).build();
        return result;
    }


    /**
     * 添加管理员用户
     * @param account
     * @param password
     * @param phone
     * @param role
     * @return
     */
    @Override
    public Admin register(String account, String password, String phone, Long role) {
        try {
            String salt = Const.SALT_PREFIX + IdUtil.fastSimpleUUID();
            Admin admin = Admin.builder().account(phone).name(account).salt(salt).password(SecureUtil.md5(salt + password)).phone(phone).role(role).status(Const.ACCOUNT_NORMAL_TAG).build();
            adminMapper.insert(admin);
            return admin;
        }catch (Exception e) {
            throw new BaseException(Status.COMMON_ERROR);
        }
    }


    /**
     * 封禁管理员
     * @param idList
     * @return
     */
    @Power(authority = Const.AUTH_ADMIN)
    @Override
    public Integer ban(List<Long> idList) {
        AtomicInteger wrong = new AtomicInteger();
        idList.forEach(id->{
            Admin admin = adminMapper.selectById(id);
            if (ObjectUtil.isNotNull(admin)) {
                // 最高管理员跳过
                if (admin.getId() != 1) {
                    admin.setStatus(Const.ACCOUNT_FROZEN_TAG);
                    int result = adminMapper.updateById(admin);
                    if (result <= 0) {
                        wrong.getAndIncrement();
                    }
                }
            }
        });
        return wrong.get();
    }

    /**
     * 解封管理员
     * @param idList
     * @return
     */
    @Power(authority = Const.AUTH_ADMIN)
    @Override
    public Integer pass(List<Long> idList) {
        AtomicInteger wrong = new AtomicInteger();
        idList.forEach(id->{
            Admin admin = adminMapper.selectById(id);
            if (ObjectUtil.isNotNull(admin)) {
                if (admin.getId() != 1) {
                    admin.setStatus(Const.ACCOUNT_NORMAL_TAG);
                    int result = adminMapper.updateById(admin);
                    if (result <= 0) {
                        wrong.getAndIncrement();
                    }
                }
            }
        });
        return wrong.get();
    }

    /**
     * 批量删除
     * @param idList
     * @return
     */
    @Override
    @Power(authority = Const.AUTH_ADMIN)
    public Integer deleteList(List<Long> idList) {
        AtomicInteger wrong = new AtomicInteger();
        idList.forEach(id->{
            if (id != 1) {
                int result = adminMapper.deleteById(id);
                if (result <= 0) {
                    wrong.getAndIncrement();
                }
            }
        });
        return wrong.get();
    }

    /**
     * 通过手机号或者用户查询 admin
     * @param queryInfo
     * @return
     */
    @Override
    public QueryResult query(String queryInfo) {
        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.or(i->i.eq("phone", queryInfo)).or(i->i.eq("name", queryInfo));
        Admin admin = adminMapper.selectOne(wrapper);
        Integer total = adminMapper.selectCount(wrapper);
        if (ObjectUtil.isNotNull(admin)) {
            Role role = roleMapper.selectById(admin.getRole());
            if (ObjectUtil.isNotNull(role)) {
                admin.setRoleName(role.getName());
            }
        }
        QueryResult result = QueryResult.builder().data(admin).total(total).build();
        return result;
    }

    /**
     * 通过id查询用户信息
     * @param id
     * @return
     */
    @Override
    @Power(authority = Const.AUTH_ADMIN)
    public Admin queryById(Long id) {
        Admin admin = adminMapper.selectById(id);
        if (ObjectUtil.isNotNull(admin)) {
            Role role = roleMapper.selectById(admin.getRole());
            if (ObjectUtil.isNotNull(role)) {
                admin.setRoleName(role.getName());
            }
        }
        return admin;
    }

    /**
     * 修改管理员的信息
     * @param name
     * @param phone
     * @param role
     * @param status
     * @param password
     * @return
     */
    @Override
    public Integer editAdmin(Long id, String name, String phone, Long role, Integer status, String password) {
        Admin admin = adminMapper.selectById(id);
        if (ObjectUtil.isNotNull(admin)) {
            if (!StrUtil.equals(admin.getPassword(), password)) {
                // 判断密码有无更改 密码若有修改 重新加密
                String newPassword = SecureUtil.md5(admin.getSalt() + password);
                admin.setPassword(newPassword);
            }
            admin.setName(name);

            admin.setAccount(phone);
            admin.setPhone(phone);

            admin.setStatus(status);
            admin.setRole(role);
            int result = adminMapper.updateById(admin);
            return result;
        }else {
            throw new BaseException(Status.ACCOUNT_NO_ERROR);
        }

    }

    /**
     * 管理员自己修改信息
     * @param id
     * @param name
     * @param phone
     * @param p1
     * @param p2
     * @return
     */
    @Override
    public Boolean ownEditInfo(Long id, String name, String phone, String p1, String p2) {
        Admin admin = adminMapper.selectById(id);
        if (ObjectUtil.isNotNull(admin)) {
            admin.setName(name);
            admin.setPhone(phone);
            if (StrUtil.equals(p1, p2)) {
                if (!StrUtil.equals(admin.getPassword(), p1)) {
                    admin.setPassword(SecureUtil.md5(admin.getSalt() + p1));
                }
                int result = adminMapper.updateById(admin);
                if (result > 0) {
                    return true;
                }else {
                    return false;
                }
            }else {
                return false;
            }
        }
        return false;
    }
}
